package com.trg.flex.dp
{
	import flash.events.EventDispatcher;
	
	import mx.collections.ArrayCollection;
	import mx.collections.CursorBookmark;
	import mx.collections.ICollectionView;
	import mx.collections.IViewCursor;
	import mx.collections.Sort;

	public class DataProviderCursor extends EventDispatcher implements IViewCursor
	{
		protected var index:int = -1;
		protected var data:ArrayCollection;
		protected var collection:ICollectionView;
		
		public function DataProviderCursor(collection:ICollectionView, data:ArrayCollection)
		{
			this.collection = collection;
			this.data = data;
		}

		public function get afterLast():Boolean
		{
			return index >= data.length;
		}
		
		public function get beforeFirst():Boolean
		{
			return index < 0;
		}
		
		public function get bookmark():CursorBookmark
		{
			return new CursorBookmark(index);
		}
		
		public function get current():Object
		{
			if (index < 0 || index >= data.length) return null;
			return data.getItemAt(index);
		}
		
		public function get view():ICollectionView
		{
			return collection;
		}
		
		public function findAny(values:Object):Boolean
		{
			var i:int = collection.sort.findItem(data.toArray(), values, Sort.ANY_INDEX_MODE);
			if (i == -1) return false;
			index = i;
			return true;
		}
		
		public function findFirst(values:Object):Boolean
		{
			var i:int = collection.sort.findItem(data.toArray(), values, Sort.FIRST_INDEX_MODE);
			if (i == -1) return false;
			index = i;
			return true;
		}
		
		public function findLast(values:Object):Boolean
		{
			var i:int = collection.sort.findItem(data.toArray(), values, Sort.LAST_INDEX_MODE);
			if (i == -1) return false;
			index = i;
			return true;
		}
		
		public function insert(item:Object):void
		{
			throw new Error("This collection is read-only");
		}
		
		public function moveNext():Boolean
		{
			index++;
			return index >= 0 && index < data.length;
		}
		
		public function movePrevious():Boolean
		{
			index--;
			return index >= 0 && index < data.length;
		}
		
		public function remove():Object
		{
			throw new Error("This collection is read-only");
		}
		
		public function seek(bookmark:CursorBookmark, offset:int=0, prefetch:int=0):void
		{
			if (bookmark.value is int) {
				index = bookmark.value as int;
			} else if (bookmark.value == "${F}") {
				index = 0;
			} else if (bookmark.value == "${L}") {
				index = data.length - 1;
			}
			
			index += offset;
		}
		
	}
}